<!--
 * @author: Goalias
 * @since: 2025-01-06
-->
<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted } from 'vue';
import { useRoute } from 'vue-router'
import { userMonitorApi, contentMonitorApi, abilityMonitorApi } from '@/apis/MonitorApi'
import { health } from '@/apis/types/Monitor'
import { ElMessage } from 'element-plus'
import { PieChart as PieChartIcon } from '@element-plus/icons-vue'
import PulsatingButton from '@/components/ui/pulsating-button';
import PieChart from '@/components/PieChart.vue';


const route = useRoute()
const project = ref<string>(route.query.project as string)
const healthMonitor = ref<health>()
const loading = ref<boolean>(false)
let intervalId: NodeJS.Timeout | null = null;
const refreshTime = ref<number>(10000)//10秒更新饼图

function handleRefresh(time: number) {
    refreshTime.value = time;
    ElMessage.success('刷新频率已更新为' + time / 1000 + '秒');
}

const serviceList = ref<{ name: string, up: boolean }[]>([
    { name: 'gateway-security服务', up: healthMonitor.value?.upServices.includes('gateway-security') },
    { name: 'user-manager服务', up: healthMonitor.value?.upServices.includes('user-manager') },
    { name: 'ability-expansion服务', up: healthMonitor.value?.upServices.includes('ability-expansion') },
    { name: 'content-integration服务', up: healthMonitor.value?.upServices.includes('content-integration') }
])

// 初始化监控数据
function initializeMonitors(project: string) {
    switch (project) {
        case 'user':
            userMonitorApi.getHealthMonitor().then(data => {
                healthMonitor.value = data.data;
                loading.value = false;
            });
            break;
        case 'content':
            contentMonitorApi.getHealthMonitor().then(data => {
                healthMonitor.value = data.data;
                loading.value = false;
            });
            break;
        case 'ability':
            abilityMonitorApi.getHealthMonitor().then(data => {
                healthMonitor.value = data.data;
                loading.value = false;
            });
            break;
        default:
            ElMessage.warning('未知项目类型');
    }
    ElMessage.success('数据已更新')
}

// 监听路由参数的变化
watch(() => route.query.project, (newProject) => {
    project.value = newProject as string;
    initializeMonitors(project.value);
});

watch(refreshTime, (newTime) => {
    if (intervalId) clearInterval(intervalId);
    intervalId = setInterval(() => {
        initializeMonitors(project.value);
    }, newTime);
});

watch(healthMonitor, (newHealthMonitor) => {
    serviceList.value = newHealthMonitor?.upServices.map(service => ({
        name: service,
        up: newHealthMonitor?.upServices.includes(service)
    }));
});

onMounted(() => {
    loading.value = true;
    initializeMonitors(project.value);
    intervalId = setInterval(() => {
        initializeMonitors(project.value);
    }, refreshTime.value);
});

onUnmounted(() => {
    clearInterval(intervalId);
});

</script>

<template>
    <div class="health-container">
        <div class="health-header">
            <span>健康监控</span>
            <span>所属服务：{{ project }}</span>
            <el-dropdown size="large" split-button type="primary">
                <span class="el-dropdown-link">
                    刷新频率
                </span>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item :icon="PieChartIcon" divided @click="handleRefresh(5000)"><span
                                class="refresh-time">5秒</span></el-dropdown-item>
                        <el-dropdown-item :icon="PieChartIcon" divided @click="handleRefresh(10000)"><span
                                class="refresh-time">10秒(默认)</span></el-dropdown-item>
                        <el-dropdown-item :icon="PieChartIcon" divided @click="handleRefresh(20000)"><span
                                class="refresh-time">20秒</span></el-dropdown-item>
                        <el-dropdown-item :icon="PieChartIcon" divided @click="handleRefresh(30000)"><span
                                class="refresh-time">30秒</span></el-dropdown-item>
                        <el-dropdown-item :icon="PieChartIcon" divided @click="handleRefresh(60000)"><span
                                class="refresh-time">60秒</span></el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <PulsatingButton pulseColor="var(--theme-color)" duration="2s" class="refresh-button"
                @click="initializeMonitors(project)" type="button">
                立即刷新
            </PulsatingButton>
        </div>
        <div class="health-body">
            <div v-if="loading">
                <el-skeleton :rows="10" />
            </div>
            <div v-else>
                <div class="service-container" >
                    <span class="service-name" v-for="service in serviceList">{{ service.name }}
                        <span :class="{ 'status-dot': true, 'status-up': service.up, 'status-down': !service.up }"></span>
                    </span>
                </div>
                <div class="health-chart-container">
                    <div class="health-jvm-container">
                        <div class="health-jvm">
                            <div class="health-status"> JVM状态: {{ healthMonitor?.status }}</div>
                            <div class="health-total"> JVM总量: {{ (healthMonitor?.jvmMemoryMax / 1024 / 1024).toFixed(2) }} (MB)</div>
                        </div>
                        <PieChart class="health-chart" :data="[
                            { value: healthMonitor?.jvmMemoryUsed / 1024 / 1024, name: 'JVM占用' },
                            { value: (healthMonitor?.jvmMemoryMax - healthMonitor?.jvmMemoryUsed) / 1024 / 1024, name: 'JVM空闲' }]"
                            name="JVM内存分布" :refreshTime="refreshTime" />
                    </div>
                    <div class="health-disk-container">
                        <div class="health-disk">
                            <div class="health-status"> 磁盘状态: {{ healthMonitor?.diskSpaceStatus }}</div>
                            <div class="health-total"> 磁盘总量: {{ (healthMonitor?.diskSpaceTotal / 1024 / 1024 / 1024).toFixed(2) }} (GB)</div>
                        </div>
                        <PieChart class="health-chart" :data="[
                            { value: (healthMonitor?.diskSpaceTotal - healthMonitor?.diskSpaceFree) / 1024 / 1024 / 1024, name: '磁盘占用' },
                            { value: healthMonitor?.diskSpaceFree / 1024 / 1024 / 1024, name: '磁盘空闲' }]" name="部署磁盘分布"
                            :refreshTime="refreshTime" />
                    </div>
                </div>
                <PieChart class="cpu-chart" :data="[
                    { value: parseFloat(healthMonitor?.systemCpuUsage), name: 'CPU使用率' },
                    { value: 100 - parseFloat(healthMonitor?.systemCpuUsage), name: 'CPU空闲率' }]" name="CPU算力分布"
                    :refreshTime="refreshTime" />
            </div>
        </div>

    </div>
</template>

<style scoped>
.health-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    margin-top: 10px;
    margin-left: 20px;
    margin-right: 20px;
}

.el-dropdown-link {
    font-size: 18px;
}

.refresh-time {
    font-size: 16px;
    color: var(--theme-color);
}

.health-chart-container {
    display: flex;
    flex-direction: space-between;
    align-items: center;
    margin-left: 5vw;
    margin-right: 5vw;
    margin-top: 3vh;
}

.health-disk-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.health-jvm-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.health-status {
    border: 1px solid #000;
    border-radius: 10px;
    padding: 10px;
    background-color: var(--theme-color);
    color: #fff;
    text-align: center;
    box-shadow: 0px 0px 60px rgba(6, 218, 229, 1);
}

.health-total {
    border: 1px solid #000;
    border-radius: 10px;
    padding: 10px;
    margin-top: 20vh;
    background-color: var(--theme-color);
    color: #fff;
    text-align: center;
    box-shadow: 0px 0px 60px rgba(6, 218, 229, 1);
}

.health-chart {
    min-width: 25vw;
}

.service-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 3vh;
    margin-left: 5vw;
    margin-right: 5vw;
}

.service-name {
    display: flex;
    align-items: center;
    color: var(--theme-color);
    box-shadow: 0px 0px 40px #febd3b;
    border-radius: 10px;
    padding: 10px;
    background-color: #f6fe84;
}

.status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-left: 1vw;
}

.status-up {
    background-color: green;
}

.status-down {
    background-color: red;
}
</style>
